package basics

import "fmt"

// Closure 闭包：闭包是一个特殊的匿名函数，它是匿名函数和相关引用环境组成的一个整体
func Closure() {
	num := 10
	a := func() {
		num++                         // 在闭包中用到了main函数中的num，所以这个匿名函数就是一个闭包
		fmt.Println("变量num的值为：", num) // 11
	}

	fmt.Println("执行闭包函数a()后，变量num的值为：", num) // 10
	a()
	fmt.Println("执行闭包函数a()后，变量num的值为：", num) // 11

	// 闭包中使用的变量和外界的变量是同一个变量，所以可以闭包中可以修改外界变量
	b := func() {
		num = 6
		fmt.Println("变量num的值为：", num) // 6
	}

	fmt.Println("执行闭包函数b()前，变量num的值为：", num) // 11
	b()
	fmt.Println("执行闭包函数b()后，变量num的值为：", num) // 6
	fmt.Println()

	// 只要闭包还在使用外界的变量，那么外界的变量就会一直存在
	res := addUpper() // 执行addUpper函数，得到一个闭包
	for i := 1; i <= 5; i++ {
		// 1,2,3,4,5
		fmt.Printf("第%2d次调用，闭包的返回值=%d\n", i, res())
	}
}
func addUpper() func() int {
	x := 0
	return func() int {
		x++ // 匿名函数中用到了addUpper中的x，所以这是一个闭包
		return x
	}
}
